<?php
/**
 ***********************************************************************************************************************
 * input核心类
 * @autor llq
 ***********************************************************************************************************************
 */
namespace artisan;
/**
 * Class input
 * @package artisan
 */
class input
{
    /**
     * GET 请求封装
     * @param string $key
     * @return mixed
     */
    public static function get($key = '', $filter = true)
    {
        if(empty($key)) {
            return $filter === true ? filter::xss($_GET) : $_GET;
        }

        if(!isset($_GET[$key])) {
            return null;
        }

        return $filter === true ? filter::xss($_GET[$key]): $_GET[$key];
    }

    /**
     * POST 请求封装
     * @param string $key
     * @return mixed
     */
    public static function post($key = '', $filter = true)
    {
        if(empty($key)) {
            return $filter === true ? filter::xss($_POST) : $_POST;
        }

        if(!isset($_POST[$key])) {
            return null;
        }

        return $filter === true ? filter::xss($_POST[$key]): $_POST[$key];
    }

    /**
     * REQUEST 请求封装
     * @param string $key
     * @return mixed
     */
    public static function any($key = '', $filter = true)
    {
        if(empty($key)) {
            return $filter === true ? filter::xss($_REQUEST) : $_REQUEST;
        }

        if(!isset($_REQUEST[$key])) {
            return null;
        }

        return $filter === true ? filter::xss($_REQUEST[$key]): $_REQUEST[$key];
    }

    /**
     * 判断请求是否是POST请求
     * @return bool
     */
    public static function isPost()
    {
        return self::getServer('REQUEST_METHOD') === 'POST';
    }

    /**
     * 判断请求是否是GET请求
     * @return bool
     */
    public static function isGet()
    {
        return self::getServer('REQUEST_METHOD') === 'GET';
    }

    /**
     * 判断请求是否是PUT请求
     * @return bool
     */
    public static function isPut()
    {
        return self::getServer('REQUEST_METHOD') === 'PUT';
    }

    /**
     * 判断请求是否是DELETE请求
     * @return bool
     */
    public static function isDelete()
    {
        return self::getServer('REQUEST_METHOD') === 'DELETE';
    }

    /**
     * 判断请求是否是OPTION请求
     * @return bool
     */
    public static function isOption()
    {
        return self::getServer('REQUEST_METHOD') === 'OPTION';
    }


    /**
     * 判断请求方法
     * @return mixed
     */
    public static function method()
    {
        return self::getServer('REQUEST_METHOD');
    }

    /**
     * 判断请求是否是AJAX并且POST请求
     * @return bool
     */
    public static function isAjaxPost()
    {
        return self::isPost() && self::isAjax();
    }

    /**
     * 判断请求是否是AJAX并且GET请求
     * @return bool
     */
    public static function isAjaxGet()
    {
        return self::isGet() && self::isAjax();
    }

    /**
     * 判断请求是否是AJAX请求
     * @return bool
     */
    public static function isAjax()
    {
        return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
    }

    /**
     * 获取当前请求url
     * @return string
     */
    public static function url()
    {
        return self::getScheme() . self::getHost() . (self::port() == '80' ? '' : ':' .self::port()) . self::uri(). self::query();
    }

    /**
     * 获取当前uri
     * @return string
     */
    public static function uri()
    {
        $ruri = self::getServer('REQUEST_URI');
        $firstPos = strpos($ruri, '?');
        if($firstPos) {
            return substr($ruri, 0, $firstPos);
        }
        return $ruri;
    }

    /**
     * 获取当前请求字符串
     * @return string
     */
    public static function query()
    {
        return self::getServer('QUERY_STRING') ? '?' . self::getServer('QUERY_STRING') : '';
    }


    /**
     * 获取当前域名
     * @return mixed
     */
    public static function getHost()
    {
        return self::getServer('HTTP_HOST');
    }

    /**
     * 获取当前请求协议
     * @return string
     */
    public static function getScheme()
    {
        return 'http://';
    }

    /**
     * @return mixed
     */
    public static function userAgent()
    {
        return self::getServer('HTTP_USER_AGENT');
    }

    /**
     * 获取当前请求使用端口
     * @return mixed
     */
    public static function port()
    {
        return self::getServer('SERVER_PORT');
    }

    /**
     * 获取当前服务器变量
     * @param string $key
     * @return mixed
     */
    public static function getServer($key = '')
    {
        if(empty($key)) {
            return $_SERVER;
        }
        return isset($_SERVER[$key]) ? $_SERVER[$key] : '';
    }

    /**
     * 请求直接重定向
     * 注意：还可以使用view::redirect(url)在前端进行重定向
     * @param string $url
     * @param int $status
     */
    public static function redirect($url = '', $status = 302)
    {
        output::redirect($url, $status);
    }

    /**
     * 真实IP
     * 避免伪造IP,优先使用REMOTE_ADDR,如果得到地址为私有网络IP,使用HTTP_X_FORWARDED_FOR的最后一个IP.
     * nginx的设置基本排除了大部分错误.如需过滤非公用地址,可增加filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)做条件, 暂时增加100.64.0.0/10的检查
     * @return string
     */
    public static function ip()
    {
        static $ip = null;
        if ($ip === null){
            $ip = empty($_SERVER['REMOTE_ADDR']) ? getenv('REMOTE_ADDR') ?: 'unknown' : $_SERVER['REMOTE_ADDR'];
            if((strpos($ip, '100.') === 0 && preg_match('#^100\.(?:6[4-9]|[7-9]\d|1[0-1]\d|12[0-7])\.#', $ip)) || $ip === 'unknown') {
                if($xForwardedForIps = empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? getenv('HTTP_X_FORWARDED_FOR') ?: '' : $_SERVER['HTTP_X_FORWARDED_FOR']){
                    $xForwardedForIps = explode(',', $xForwardedForIps);
                    $ip = trim(array_pop($xForwardedForIps));
                }
            }
        }
        return $ip;
    }

    /*
     * 检查是否为HTTPS请求协议
     * */
    public static function isHttps()
    {
        if (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off')
        {
            return true;
        }
        if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
        {
            return true;
        }
        if (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off')
        {
            return true;
        }

        return false;
    }

    /**
     * 重复请求检查
     * @param int $cacheTimeout
     * @param boolean $raise
     * @return boolean
     */
    public static function reSubmitCheck($cacheTimeout = 60, $raise = false)
    {
        /////////////////防止并发访问（客户连续点击提交按钮）
       $concurrentKey = 'OP:' . md5(self::url().json_encode($_REQUEST));
        if (cache::get($concurrentKey)) {
            if($raise){
                raise(1108, '请等待操作完成，勿连续点击:'.$cacheTimeout);
            }
           return false;
        }
        cache::set($concurrentKey, 1, $cacheTimeout);
        return true;
    }
}
